// ==UserScript==
// @name         海螺AI视频下载器
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  自动下载海螺AI视频
// @author       土豆君(tudoujunh)
// @match        https://hailuoai.video
// @match        https://hailuoai.com/video
// @grant        GM_download
// @connect      hailuoai.video
// @connect      hailuoai.com
// @updateURL    https://gitee.com/tudoujunha/rpa-gpt/raw/master/hailuoai_down.user.js
// @downloadURL  https://gitee.com/tudoujunha/rpa-gpt/raw/master/hailuoai_down.user.js
// ==/UserScript==

(function() {
    'use strict';

    let videoList = [];
    let isListening = true; // 监听开关状态

    // 添加控制面板
    function addControlPanel() {
        const panel = document.createElement('div');
        panel.className = 'download-control-panel';

        // 添加样式
        const style = document.createElement('style');
        style.textContent = `
            .download-control-panel {
                position: fixed;
                left: 20px;
                top: 50%;
                transform: translateY(-50%);
                background-color: rgba(26, 26, 26, 0.95);
                color: white;
                border: 1px solid #333;
                border-radius: 4px;
                padding: 10px;
                z-index: 9999;
                width: 160px;
                box-shadow: 0 2px 10px rgba(0,0,0,0.3);
                cursor: move;
                user-select: none;
            }
            .control-item {
                margin-bottom: 8px;
                padding: 2px;
            }
            .control-item label {
                display: block;
                margin-bottom: 3px;
                color: #fff;
                font-size: 12px;
            }
            .control-item input[type="number"] {
                width: 100%;
                padding: 3px;
                background-color: #333;
                color: white;
                border: 1px solid #555;
                border-radius: 4px;
                font-size: 12px;
                box-sizing: border-box;
            }
            .control-item select {
                width: 100%;
                padding: 3px;
                background-color: #333;
                color: white;
                border: 1px solid #555;
                border-radius: 4px;
                font-size: 12px;
                box-sizing: border-box;
            }
            .download-btn {
                background-color: #4CAF50;
                color: white;
                border: none;
                padding: 6px 12px;
                border-radius: 4px;
                cursor: pointer;
                margin-top: 8px;
                width: 100%;
                font-size: 12px;
            }
            .download-btn:hover {
                background-color: #45a049;
            }
            .toggle-switch {
                position: relative;
                display: inline-block;
                width: 40px;
                height: 20px;
            }
            .toggle-switch input {
                opacity: 0;
                width: 0;
                height: 0;
            }
            .slider {
                position: absolute;
                cursor: pointer;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background-color: #ccc;
                transition: .4s;
                border-radius: 20px;
            }
            .slider:before {
                position: absolute;
                content: "";
                height: 16px;
                width: 16px;
                left: 2px;
                bottom: 2px;
                background-color: white;
                transition: .4s;
                border-radius: 50%;
            }
            input:checked + .slider {
                background-color: #2196F3;
            }
            input:checked + .slider:before {
                transform: translateX(20px);
            }
            #download-status {
                margin-top: 8px;
                padding: 4px;
                background-color: rgba(0,0,0,0.5);
                border-radius: 4px;
                display: none;
                font-size: 12px;
            }
            #toggle-status {
                display: inline-block;
                vertical-align: middle;
            }
            .control-item {
                display: flex;
                align-items: center;
            }
            .pin-checkbox {
                margin-right: 5px;
                vertical-align: middle;
            }
            .download-control-panel.pinned {
                cursor: default;
            }
        `;
        document.head.appendChild(style);

        // 面板内容
        panel.innerHTML = `
            <div class="control-item">
                <label class="toggle-switch">
                    <input type="checkbox" id="listen-toggle" checked>
                    <span class="slider"></span>
                </label>
                <span id="toggle-status" style="margin-left: 10px;">已开启</span>
            </div>
            <div class="control-item">
                <label>
                    <input type="checkbox" id="pin-checkbox" class="pin-checkbox" checked>
                    固定位置
                </label>
            </div>
            <div class="control-item">
                <label>已捕获视频数: <span id="video-count">0</span></label>
            </div>
            <div class="control-item">
                <label>下载数量 (输入数字)</label>
                <input type="number" id="download-count" min="1" value="1" placeholder="输入数量">
            </div>
            <div class="control-item">
                <label>下载顺序</label>
                <select id="download-order">
                    <option value="desc">ID从大到小</option>
                    <option value="asc">ID从小到大</option>
                </select>
            </div>
            <button class="download-btn" id="download-btn">开始下载</button>
            <div id="download-status"></div>
        `;

        document.body.appendChild(panel);

        // 绑定事件
        const listenToggle = document.getElementById('listen-toggle');
        const toggleStatus = document.getElementById('toggle-status');
        const downloadBtn = document.getElementById('download-btn');

        listenToggle.addEventListener('change', (e) => {
            isListening = e.target.checked;
            toggleStatus.textContent = isListening ? '已开启' : '已关闭';
            showStatus(isListening ? '监听已开启' : '监听已关闭');
        });

        downloadBtn.addEventListener('click', startDownload);

        // 初始化变量
        let isDragging = false;
        let currentX = 0;
        let currentY = 0;
        let initialX = 0;
        let initialY = 0;
        let xOffset = 20;
        let yOffset = window.innerHeight / 4;
        let isPinned = true; // 默认固定

        // 钉住状态变化事件
        const pinCheckbox = document.getElementById('pin-checkbox');
        pinCheckbox.addEventListener('change', (e) => {
            isPinned = e.target.checked;
            if (isPinned) {
                panel.classList.add('pinned');
            } else {
                panel.classList.remove('pinned');
            }
        });

        // 初始化时添加pinned类
        panel.classList.add('pinned');

        // 修改拖动开始判断
        function dragStart(e) {
            if (isPinned) return;

            // 使用相对于视口的位置计算
            initialX = e.clientX - xOffset;
            initialY = e.clientY - yOffset;

            if (e.target === panel || panel.contains(e.target)) {
                if (!e.target.tagName.match(/button|input|select/i)) {
                    isDragging = true;
                }
            }
        }

        function drag(e) {
            if (isDragging && !isPinned) {
                e.preventDefault();

                currentX = e.clientX - initialX;
                currentY = e.clientY - initialY;

                // 限制拖动范围
                const maxX = window.innerWidth - panel.offsetWidth;
                const maxY = window.innerHeight - panel.offsetHeight;

                xOffset = Math.min(Math.max(0, currentX), maxX);
                yOffset = Math.min(Math.max(0, currentY), maxY);

                // 使用 left 和 top 代替 transform
                panel.style.left = `${xOffset}px`;
                panel.style.top = `${yOffset}px`;
                panel.style.transform = 'none'; // 移除 transform
            }
        }

        // 设置初始位置
        panel.style.left = `${xOffset}px`;
        panel.style.top = `${yOffset}px`;
        panel.style.transform = 'none';

        // 修改拖动结束事件
        function dragEnd(e) {
            if (isDragging && !isPinned) { // 添加钉住检查
                initialX = currentX;
                initialY = currentY;
                isDragging = false;
            }
        }

        // 添加拖动事件监听
        panel.addEventListener('mousedown', dragStart, false);
        document.addEventListener('mousemove', drag, false);
        document.addEventListener('mouseup', dragEnd, false);

        // 防止点击事件冒泡导致拖动问题
        panel.addEventListener('click', (e) => {
            if (e.target.tagName === 'BUTTON' ||
                e.target.tagName === 'INPUT' ||
                e.target.tagName === 'SELECT' ||
                e.target.classList.contains('pin-checkbox')) {
                e.stopPropagation();
            }
        });
    }

    // 更新视频计数
    function updateVideoCount() {
        const countElement = document.getElementById('video-count');
        if (countElement) {
            countElement.textContent = videoList.length;
        }
    }

    // 开始下载
    function startDownload() {
        const countInput = document.getElementById('download-count');
        const orderSelect = document.getElementById('download-order');

        const count = parseInt(countInput.value) || 1;
        const order = orderSelect.value;

        // 排序视频列表
        const sortedVideos = [...videoList].sort((a, b) => {
            const compareResult = a.id.localeCompare(b.id);
            return order === 'desc' ? -compareResult : compareResult;
        });

        // 获取指定数量的视频
        const videosToDownload = sortedVideos.slice(0, count);

        if (videosToDownload.length > 0) {
            downloadVideos(videosToDownload);
            showStatus(`开始下载 ${videosToDownload.length} 个视频...`);
        } else {
            showStatus('没有找到可下载的视频');
        }
    }

    // 显示状态信息
    function showStatus(message) {
        const status = document.getElementById('download-status');
        if (status) {
            status.textContent = message;
            status.style.display = 'block';
            setTimeout(() => {
                status.style.display = 'none';
            }, 3000);
        }
    }

    // 下载视频
    function downloadVideos(videos) {
        videos.forEach((video, index) => {
            setTimeout(() => {
                GM_download({
                    url: video.url,
                    name: video.filename,
                    onload: () => {
                        console.log(`已下载: ${video.filename}`);
                        showStatus(`已下载: ${video.filename}`);
                    },
                    onerror: (error) => {
                        console.error(`下载失败: ${video.filename}`, error);
                        showStatus(`下载失败: ${video.filename}`);
                    }
                });
            }, index * 1500);
        });
    }

    // 代理 XHR 以监听请求
    function proxyXHR() {
        const XHR = XMLHttpRequest.prototype;
        const open = XHR.open;
        const send = XHR.send;

        XHR.open = function(method, url) {
            this._url = url;
            return open.apply(this, arguments);
        };

        XHR.send = function() {
            this.addEventListener('load', function() {
                if (!isListening) return; // 如果监听关闭，直接返回

                // 检查是否是目标API
                if (this._url.includes('/v2/api/multimodal/video/my/cursor')) {
                    try {
                        const response = JSON.parse(this.responseText);
                        if (response.data && response.data.videos) {
                            const newVideos = response.data.videos
                                .filter(item => item.downloadURL)
                                .map(item => ({
                                    id: item.id,
                                    url: item.downloadURL,
                                    filename: `hailuo_${item.id}.mp4`
                                }));

                            // 更新视频列表，避免重复ID
                            const existingIds = new Set(videoList.map(v => v.id));
                            newVideos.forEach(video => {
                                if (!existingIds.has(video.id)) {
                                    videoList.push(video);
                                    existingIds.add(video.id);
                                }
                            });

                            updateVideoCount();
                            showStatus(`已加载 ${videoList.length} 个视频`);
                            console.log('找到新的视频:', newVideos.length);
                        }
                    } catch (error) {
                        console.error('解析响应数据失败:', error);
                    }
                }
            });
            return send.apply(this, arguments);
        };
    }

    // 初始化
    function init() {
        proxyXHR();
        addControlPanel();
    }

    // 页面加载完成后初始化
    window.addEventListener('load', init);
})();